#include "pch.h"
#include "math.hpp"

/*#include "Point.h"
#include "Sphere.h"
#include "AABB.h"
#include "OBB.h"
#include "Ray.h"
#include "Line.h"*/




//
// Integration into boost::type_traits
//
// All instantiations of vectorX, matrixXxX, color and Point with POD-integral types should
// have a trivial copy-constructor and trivial assignment, so that they can be used efficiently
// in some algorithms.
//
#define HAS_TRIVIAL_ASSIGN(T)   BOOST_STATIC_ASSERT(boost::has_trivial_assign<T>::value == true);
#define HAS_TRIVIAL_COPY(T)     BOOST_STATIC_ASSERT(boost::has_trivial_copy<T>::value == true);
#define IS_TRIVIAL(T)           HAS_TRIVIAL_ASSIGN(T) HAS_TRIVIAL_COPY(T)

IS_TRIVIAL(math::color);
IS_TRIVIAL(math::vector2< math::number<float> >);
IS_TRIVIAL(math::vector3< math::number<float> >);
IS_TRIVIAL(math::vector4< math::number<float> >);
IS_TRIVIAL(math::matrix2x2< math::number<float> >);
IS_TRIVIAL(math::matrix3x3< math::number<float> >);
IS_TRIVIAL(math::matrix4x4< math::number<float> >);
IS_TRIVIAL(math::rectangle< math::number<float> >);
IS_TRIVIAL(math::rectangle< math::number<double> >);

// In case you're uncertain this is working properly:
// The next test should rise 2 compilation errors, since std::string neither
// has a trivial copy constructor, nor assignment operator
// IS_TRIVIAL(std::string);

//
// Memory size & layout
//
#define HAS_SIZE(T, s)   BOOST_STATIC_ASSERT(sizeof(T) == s)
#define HAS_OFFSET(T, a, o)   BOOST_STATIC_ASSERT(offsetof(T, a) == o)
#define HAS_LAYOUT2(T, a1, a2)   HAS_SIZE(T, 2 * sizeof(T::float_t)); HAS_OFFSET(T, a1, 0*sizeof(T::float_t)); HAS_OFFSET(T, a2, 1*sizeof(T::float_t));
#define HAS_LAYOUT3(T, a1, a2, a3)   HAS_SIZE(T, 3 * sizeof(T::float_t)); HAS_OFFSET(T, a1, 0*sizeof(T::float_t)); HAS_OFFSET(T, a2, 1*sizeof(T::float_t)); HAS_OFFSET(T, a3, 2*sizeof(T::float_t));
#define HAS_LAYOUT4(T, a1, a2, a3, a4)   HAS_SIZE(T, 4 * sizeof(T::float_t)); HAS_OFFSET(T, a1, 0*sizeof(T::float_t)); HAS_OFFSET(T, a2, 1*sizeof(T::float_t)); HAS_OFFSET(T, a3, 2*sizeof(T::float_t)); HAS_OFFSET(T, a4, 3*sizeof(T::float_t));
#define HAS_LAYOUT9(T, a1, a2, a3, a4, a5, a6, a7, a8, a9)    HAS_SIZE(T, 9 * sizeof(T::float_t)); HAS_OFFSET(T, a1, 0*sizeof(T::float_t)); HAS_OFFSET(T, a2, 1*sizeof(T::float_t)); HAS_OFFSET(T, a3, 2*sizeof(T::float_t)); HAS_OFFSET(T, a4, 3*sizeof(T::float_t)); HAS_OFFSET(T, a5, 4*sizeof(T::float_t)); HAS_OFFSET(T, a6, 5*sizeof(T::float_t)); HAS_OFFSET(T, a7, 6*sizeof(T::float_t)); HAS_OFFSET(T, a8, 7*sizeof(T::float_t)); HAS_OFFSET(T, a9, 8*sizeof(T::float_t));
#define HAS_LAYOUT16(T, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15, a16)    HAS_SIZE(T, 16 * sizeof(T::float_t)); HAS_OFFSET(T, a1, 0*sizeof(T::float_t)); HAS_OFFSET(T, a2, 1*sizeof(T::float_t)); HAS_OFFSET(T, a3, 2*sizeof(T::float_t)); HAS_OFFSET(T, a4, 3*sizeof(T::float_t)); HAS_OFFSET(T, a5, 4*sizeof(T::float_t)); HAS_OFFSET(T, a6, 5*sizeof(T::float_t)); HAS_OFFSET(T, a7, 6*sizeof(T::float_t)); HAS_OFFSET(T, a8, 7*sizeof(T::float_t)); HAS_OFFSET(T, a9, 8*sizeof(T::float_t)); HAS_OFFSET(T, a10, 9*sizeof(T::float_t)); HAS_OFFSET(T, a11, 10*sizeof(T::float_t)); HAS_OFFSET(T, a12, 11*sizeof(T::float_t)); HAS_OFFSET(T, a13, 12*sizeof(T::float_t)); HAS_OFFSET(T, a14, 13*sizeof(T::float_t)); HAS_OFFSET(T, a15, 14*sizeof(T::float_t)); HAS_OFFSET(T, a16, 15*sizeof(T::float_t));

HAS_LAYOUT2(math::vector2< math::number<float> >, x, y);
HAS_LAYOUT3(math::vector3< math::number<float> >, x, y, z);
HAS_LAYOUT4(math::vector4< math::number<float> >, x, y, z, w);
HAS_LAYOUT4(math::matrix2x2< math::number<float> >, _11, _12, _21, _22);
HAS_LAYOUT9(math::matrix3x3< math::number<float> >, _11, _12, _13, _21, _22, _23, _31, _32, _33);
HAS_LAYOUT16(math::matrix4x4< math::number<float> >, _11, _12, _13, _14, _21, _22, _23, _24, _31, _32, _33, _34, _41, _42, _43, _44);
